package org.zjx.analysis.util;

import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringMatcherUtil {

    /**
     * 匹配任务模板并提取变化的关键词
     *
     * @param template 任务模板字符串，包含占位符 {placeholder}
     * @param content 详细的任务内容
     * @return 匹配结果对象，包含匹配状态和提取的关键词
     */
    public static MatchResult matchString(String template, String content) {
        // 1. 从模板中提取所有占位符
        List<String> placeholders = extractPlaceholders(template);

        // 2. 将模板转换为正则表达式
        String regex = convertToRegex(template);

        // 3. 使用正则表达式匹配内容
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);

        // 4. 创建匹配结果对象
        MatchResult result = new MatchResult();

        if (matcher.find()) {
            result.setMatched(true);

            // 提取匹配到的关键词
            for (int i = 0; i < placeholders.size(); i++) {
                String placeholder = placeholders.get(i);
                String keyword = matcher.group(i + 1); // group(0)是整个匹配，所以从1开始
                result.addKeyword(placeholder, keyword);
            }
        } else {
            result.setMatched(false);
        }

        return result;
    }

    /**
     * 从模板中提取所有占位符
     */
    private static List<String> extractPlaceholders(String template) {
        List<String> placeholders = new ArrayList<>();
        Pattern pattern = Pattern.compile("\\{([^}]+)\\}");
        Matcher matcher = pattern.matcher(template);

        while (matcher.find()) {
            placeholders.add(matcher.group(1)); // 获取占位符名称（去掉大括号）
        }

        return placeholders;
    }

    /**
     * 将模板转换为正则表达式
     */
    private static String convertToRegex(String template) {
        // 1. 提取占位符并创建唯一标记
        List<String> placeholders = extractPlaceholders(template);
        String tempTemplate = template;

        // 使用唯一标记替换原始占位符（如@@PH_0@@）
        for (int i = 0; i < placeholders.size(); i++) {
            String marker = "@@PH_" + i + "@@";
            tempTemplate = tempTemplate.replace(
                    "{" + placeholders.get(i) + "}",
                    marker
            );
        }

        // 2. 转义非占位符部分的正则特殊字符
        String escaped = tempTemplate.replaceAll(
                "([\\\\\\[\\](){}^$.|?*+])",
                "\\\\$1"
        );

        // 3. 将标记替换为捕获组
        String regex = escaped;
        for (int i = 0; i < placeholders.size(); i++) {
            String marker = "@@PH_" + i + "@@";
            regex = regex.replace(marker, "(.+?)");
        }

        // 4. 确保匹配整个字符串
        return "^" + regex + "$";
    }

    /**
     * 匹配结果对象
     */
    @Data
    public static class MatchResult {
        private boolean matched;
        private List<Keyword> keywords = new ArrayList<>();

        public void addKeyword(String placeholder, String keyword) {
            keywords.add(new Keyword(placeholder, keyword));
        }

        @Override
        public String toString() {
            if (!matched) {
                return "MatchResult: not matched";
            }

            StringBuilder sb = new StringBuilder("MatchResult: matched\n");
            sb.append("Extracted keywords:\n");
            for (Keyword kw : keywords) {
                sb.append("  ").append(kw.placeholder).append(": ").append(kw.keyword).append("\n");
            }
            return sb.toString();
        }
    }

    /**
     * 关键词对象
     */
    @Data
    public static class Keyword {
        private String placeholder;
        private String keyword;

        public Keyword(String placeholder, String keyword) {
            this.placeholder = placeholder;
            this.keyword = keyword;
        }

    }

    public static void main(String[] args) {
        // 测试用例
        String template = "去{地点}找{NPC}对话";
        String content = "去长安城找李四对话";

        MatchResult result = matchString(template, content);
        System.out.println(result);

        // 另一个测试用例
        template = "完成{任务名称}需要{数量}个{物品}";
        content = "完成收集草药需要15个药草";

        result = matchString(template, content);
        System.out.println(result);

        // 不匹配的测试用例
        template = "击败{怪物}获得{奖励}";
        content = "完成任务获得金币";
        result = matchString(template, content);
        System.out.println(result);


        template = "帮师傅抓到{宠物名}，当前第{任务次数}次。";
        content = "帮师傅抓到虾兵，当前第6次。";
        result = matchString(template, content);
        System.out.println(result);

    }
}
